﻿//  --------------------------------
//  Copyright (c) AW Systems, Inc. All rights reserved.
//  This source code is made available under the terms of the Microsoft Public License (Ms-PL)
//  http://www.codeplex.com/SLAM/license
//  ---------------------------------

using System;
using AWS.SLAM.Configuration;
using AWS.SLAM.Data;
using AWS.SLAM.Events;
using AWS.SLAM.Hierarchy.Data;
using AWS.SLAM.Logging;
using AWS.SLAM.SharePoint;
using Microsoft.SharePoint;
using System.Text.RegularExpressions;

namespace AWS.SLAM.Hierarchy
{
	/// <summary>
	/// HierarchicalContentTypeItemDeleter appropriatley removes an item from the hierarchy of items
	/// managed in SLAM's datasource(s) then deletes the item in SLAM when a List Item 
	/// configured to be managed by SLAM according to its Content Type is deleted in SharePoint.  
	/// 
	/// A Content Type in SharePoint configured to use the HierarchicalContentTypeItemDeleter requires 
	/// that it contain a field of type HierarchyPositionField.
	/// </summary>
	public class HierarchicalContentTypeItemDeleter : ContentTypeItemDeleter
	{
		#region Private State

		/// <summary>
		/// SLAM Data service layer
		/// </summary>
		private IDataServices _dataServices;

		/// <summary>
		/// SLAM Configuration
		/// </summary>
		private IConfigurationManager _configuration;

		/// <summary>
		/// SLAM Logger
		/// </summary>
		private ILogger _logger;

		#endregion

		#region Constructors

		/// <summary>
		/// Creates instance of HierarchicalContentTypeItemDeleter for the given 
		/// DataServices, Configuration, and Logger.
		/// </summary>
		/// <param name="dataServices"></param>
		/// <param name="configuration"></param>
		/// <param name="logger"></param>
		public HierarchicalContentTypeItemDeleter(IDataServices dataServices, IConfigurationManager configuration, ILogger logger)
			: base(dataServices, configuration, logger)
		{
			_dataServices = dataServices;
			_configuration = configuration;
			_logger = logger;
		}

		#endregion

		/// <summary>
		/// Deletes an item from the hierarchy managed by SLAM for the List Item's Content Type and removes
		/// its children if any exist from the hierarchy, without completely deleting each item, then it
		/// deletes the item from SLAM's external datasource.
		/// </summary>
		/// <param name="listItem"></param>
		/// <returns></returns>
		public override bool Delete(SPListItem listItem)
		{
			string typeName = SlamItemContext.TypeName;

			//Open Hierarchy's DataService with the Default ConnectionString and DataSchema.
			//This process assumes the Hierarchy is saved in a SQL Server database and is using
			//a SLAM XML Configuration file.
			DataService dataService = new DataService(_configuration.GetSection<ConnectionStringSection>("ConnectionStrings").Default,
				((XmlSqlDataMapping)_configuration.DataMapping).GetDataSchema());

			//Check configuration for the presence of a TableName for the listItem's
			//ContentType.  If it is present, use it as the item's typeName instead of the
			//ContentType Name.  Otherwise if it is not present use the ContentType's Name
			string itemTypeName = _configuration.DataMapping.GetTypeAttribute("", typeName, "TableName");
			if (String.IsNullOrEmpty(itemTypeName))
			{
				itemTypeName = typeName;
			}

			TypeIdDefinition typeIdDefinition = new TypeIdDefinition();
			string typeIdDefinitionName = _configuration.DataMapping.GetTypeAttribute("", typeName, "TypeIdDefinition");
			if (String.IsNullOrEmpty(typeIdDefinitionName))
			{
				typeIdDefinitionName = ((XmlSqlDataMapping)_configuration.DataMapping).GetTypeIdDefinitionName();
			}
			TypeIdDefinitionSection typeIdDefininitionSection = _configuration.GetSection<TypeIdDefinitionSection>("TypeIdDefinitions");

			if (String.IsNullOrEmpty(typeIdDefinitionName))
			{
				typeIdDefinition = typeIdDefininitionSection.Default;
			}
			else
			{
				typeIdDefinition = typeIdDefininitionSection.GetTypeIdDefinition(typeIdDefinitionName);
			}

			string idColumnName = Regex.Replace(String.IsNullOrEmpty(typeIdDefinition.NameFormat) ? "ID" : typeIdDefinition.NameFormat.Replace("{TypeName}", _configuration.DataMapping.GetTypeAttribute("", typeName, "Name")).Replace("{TableName}", itemTypeName), "[\\W\\s]", "");

			//For this type, add the Hierarchy "Left", "Right", and "Hierarchy Level" columns
			//in the SLAM table if they do not exist.
			dataService.AddHierarchyColumns(itemTypeName);

			dataService.DeleteNode(itemTypeName, idColumnName, Convert.ToString(listItem.GetUniqueId()));

			dataService.RecalculateHierarchyLevels(itemTypeName, idColumnName);

			//Execute default SLAM Delete process for a configured Content Type
			return base.Delete(listItem);
		}
	}
}
